

#include <event.h>
#include <stdint.h>
#include "radclt.h"
#include "log.h"
#include "sess.h"
#include "db.h"

//#include "wtpnl.h"
//#include "nacStationDB.h"

#define SERVER_IP_LEN	16
#define SERVER_SECRET	126

#define NAC_AUTH_METHOD_RADIUS			1		//	radius认证
#define NAC_AUTH_METHOD_LOCAL			2 		//	本地认证
#define NAC_AUTH_METHOD_HTTP			3		//  HTTP认证
#define NAC_AUTH_METHOD_LDAP			4		//  ldap认证
#define NAC_AUTH_METHOD_PRE_USER		5		//  每用户认证

typedef struct {
	uint16_t authport;
	uint16_t acctport;
	uint32_t acctFlag;				//  stop可靠记账标记，0表示不可靠，1表示可靠
	int acct_op;			//0: 表示接受radius认证成功报文就让用户上线, 1 ：表示接受到radius的开始记账响应报文才让用户上线
	int auth_type;
	int mac_auth;
	char nasip[SERVER_IP_LEN];
	char srvIp[SERVER_IP_LEN];
	char secret[SERVER_SECRET];
	char http_url[SERVER_SECRET];
	radclt_t *radauth;
	radclt_t *radacct;
	radclt_t *radDM;
        radclt_t *radCoA;
} Auth_srv_t;

Auth_srv_t G_auth;

int ReadAuthInfoFromConfigFile(void);

void RadAuthServerCallBack(int fd, short event, void *arg);

void RadAcctServerCallBack(int fd, short event, void *arg);

void RadDMServerCallBack(int fd, short event, void *arg);

static inline char *nacAuthTypeToString(int type)
{
	switch(type) {
	case NAC_AUTH_METHOD_HTTP:
			return "HTTP";
	case NAC_AUTH_METHOD_LDAP:
			return "LDAP";
	case NAC_AUTH_METHOD_LOCAL:
			return "LOCAL";
	case NAC_AUTH_METHOD_RADIUS:
			return "RADIUS";
	case NAC_AUTH_METHOD_PRE_USER :
			return "Pre-User";
	default:
			return "Unknown";
	}
}

static inline void nacMSGdebug(db_sta_t *sta, char *type, char *acct_type,
		uint32_t session_time, uint32_t ingiga, uint32_t inbyte, uint64_t inpackets,
		uint32_t outgiga, uint32_t outbyte, uint64_t outpackets)
{
	uint8_t *ip = (uint8_t *)&sta->ip;
	DEBUG("Receive/Send %s packet :\n"
			"	Acct-Status-Type = %s\n"
			"	Acct-Session-Id = \"%s\"\n"
			"	Framed-IP-Address = %u.%u.%u.%u\n"
			"	Calling-Station-Id = %02X:%02X:%02X:%02X:%02X:%02X\n"
			"	User-Name = \"%s\"\n"
			"	Acct-Session-Time = %u\n"
			"	Acct-Input-Octets = %u\n"
			"	Acct-Input-Gigawords = %u\n"
			"	Acct-Input-Packets = %llu\n"
			"	Acct-Output-Gigawords = %u\n"
			"	Acct-Output-Octets = %u\n"
			"	Acct-Output-Packets = %llu",
			type, acct_type, sta->acct_session_id, ip[0], ip[1], ip[2], ip[3],
			sta->mac[0], sta->mac[1], sta->mac[2], sta->mac[3], sta->mac[4], sta->mac[5],
			sta->user_name, session_time, inbyte, ingiga, inpackets, outgiga, outbyte, outpackets);
}

static inline void nacReplyMSGdebug(uint32_t session_time, uint32_t inspeed, uint32_t outspeed,
		char *username, int32_t sta_ip, uint32_t gflow, uint32_t bflow, uint8_t *mac
#ifdef typedata_defined
		, char *typedataURL, uint32_t quotaOfday, uint32_t quotaOfmon
#endif
)
{
	uint8_t *ip = (uint8_t *)&sta_ip;
	DEBUG("Receive packet:\n"
			"	User-Name = \"%s\"\n"
			"	Station-MAC = %02x:%02x:%02x:%02x:%02x:%02x\n"
			"	Framed-IP-Address = %u.%u.%u.%u\n"
			"	Session-Timeout = %u\n"
			"	Rate-Input = %u\n"
			"	Rate-Output = %u\n"
			"	Max-Giga-Flow = %u\n"
			"	Max-Flow = %u"
#ifdef typedata_defined
			"\n	POLICY_URL = %s\n"
			"	Day-Limit-Flow = %u\n"
			"	Mon-Limit-Flow = %u"
#endif
			,username, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
			ip[0], ip[1], ip[2], ip[3],
			session_time, inspeed, outspeed, gflow, bflow
#ifdef typedata_defined
			, typedataURL, quotaOfday, quotaOfmon
#endif
			);
}
static inline void nacDMrequsetMSGdebug(char *username, char *sessidstr, int32_t staip)
{
	uint8_t * p = (uint8_t *) &staip;
	DEBUG("Received DROP-REQ :\n"
			"	User-Name = %s\n"
			"	Acct-Session-Id = %s\n"
			"	Framed-IP-Address = %d.%d.%d.%d",
			username?username:"NULL", sessidstr, p[0], p[1], p[2], p[3]);
}

static inline void nacRadAuthRequsetdebug(uint8_t id,int32_t staip
		, const char *username, const char *calledId, const char *userpasswd, const char *usermac)
{
	uint8_t *ip = (uint8_t *)&staip;
	DEBUG("Sending Access-Request of id %u to %s port %u \n"
			"	User-Name = \"%s\"\n"
			"	User-Password = \"%s\"\n"
			"	Framed-IP-Address = %u.%u.%u.%u\n"
			"	Called-Station-Id = \"%s\"\n"
			"	Calling-Station-Id = \"%s\"\n"
			"	NAS-IP-Address = %s", id, G_auth.srvIp, G_auth.authport,
			username, userpasswd, ip[0], ip[1], ip[2], ip[3], calledId,
			usermac, G_auth.nasip);
}
int nacRadiusAuthMSGParse(radmsg_t *msg, uint32_t *sesstime, uint32_t* outspeed,
		uint32_t *inspeed, uint32_t *gflow, uint32_t *bflow, char *username, char *sessidstr);

